package com.cavy.platform.server.domain;

import com.cavy.platform.server.validator.PluginContainerData;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

@Data
public class Plugin {
    public static final String LATEST_VERSION = "latest";
    //名称
    private String name;
    private String version;
    //描述(md格式)
    @JsonIgnore
    private String description;
    //镜像
    private String image;
    //命令
    private String command;
    //运行插件的user
    private String user;
    //挂载的卷
    // container_path,host_path,tips
    private List<PluginVolume> volumes = new ArrayList<>();
    //环境变量
    // name,value,tips
    private List<PluginEnvironment> environments = new ArrayList<>();
    //工作目录
    private String workDir;
    //创建时间
    private Date createTime;
    //是否禁用
    private boolean disable = false;
    //仓库信息
    private PluginRepositorySetting repositoryInfo;

    public List<ValidateError> validate(PluginContainerData value) {
        List<ValidateError> errors = new ArrayList<>();
        if (!image.equals(value.getImage())) {
            errors.add(new ValidateError("镜像名称不一致", value.getImageFieldName()));
        }
        if (!command.equals(value.getCommand())) {
            errors.add(new ValidateError("命令名称不一致", value.getCommandFieldName()));
        }
        if (!user.equals(value.getUser())) {
            errors.add(new ValidateError("用户名称不一致", value.getUserFieldName()));
        }
        errors.addAll(validateVolumes(value));
        errors.addAll(validateEnvironments(value));
        if (!workDir.equals(value.getWorkDir())) {
            errors.add(new ValidateError("工作目录名称不一致", value.getWorkDirFieldName()));
        }
        return errors;
    }

    private List<ValidateError> validateEnvironments(PluginContainerData value) {
        List<ValidateError> result = new ArrayList<>(0);
        List<? extends ContainerEnvironmentData> environmentsDtos = value.getEnvironments();
        int size = environmentsDtos.size();
        if (size != this.environments.size()) {
            result.add(new ValidateError("环境变量数量与插件不匹配", value.getEnvironmentsFieldName()));
        }
        sortEnvironmentsDtos(environmentsDtos);
        sortEnvironments(environments);
        for (int i = 0; i < size; i++) {
            PluginEnvironment environment = this.environments.get(i);
            ContainerEnvironmentData data = environmentsDtos.get(i);
            ValidateError error = environment.validate(data);
            if (error != null) {
                result.add(new ValidateError(error.getMessage(), value.getEnvironmentsFieldName() + "[" + i + "]." + error.getFieldName()));
            }
        }
        return result;
    }

    private void sortEnvironments(List<PluginEnvironment> environments) {
        environments.sort(new Comparator<PluginEnvironment>() {
            @Override
            public int compare(PluginEnvironment o1, PluginEnvironment o2) {
                return o1.getName().compareTo(o2.getName());
            }
        });
    }

    private void sortEnvironmentsDtos(List<? extends ContainerEnvironmentData> environmentsDtos) {
        environmentsDtos.sort(new Comparator<ContainerEnvironmentData>() {
            @Override
            public int compare(ContainerEnvironmentData o1, ContainerEnvironmentData o2) {
                return o1.getName().compareTo(o2.getName());
            }
        });
    }

    /**
     * 元素数量一致
     */
    private List<ValidateError> validateVolumes(PluginContainerData value) {
        List<ValidateError> result = new ArrayList<>(0);
        List<? extends ContainerVolumeData> volumeDtos = value.getVolumes();
        int size = volumeDtos.size();
        if (size != this.volumes.size()) {
            result.add(new ValidateError("挂载的卷数量与插件定义不匹配", value.getVolumesFieldName()));
        }
        sortDtos(volumeDtos);
        sort(volumes);
        for (int i = 0; i < size; i++) {
            PluginVolume pluginVolume = this.volumes.get(i);
            ContainerVolumeData containerVolumeData = volumeDtos.get(i);
            ValidateError error = pluginVolume.validate(containerVolumeData);
            if (error != null) {
                result.add(new ValidateError(error.getMessage(), value.getVolumesFieldName() + "[" + i + "]." + error.getFieldName()));
            }
        }
        return result;
    }

    private void sort(List<PluginVolume> volumes) {
        volumes.sort(new Comparator<PluginVolume>() {
            @Override
            public int compare(PluginVolume o1, PluginVolume o2) {
                return o1.getContainerPath().compareTo(o2.getContainerPath());
            }
        });
    }

    private void sortDtos(List<? extends ContainerVolumeData> volumeDtos) {
        volumeDtos.sort(new Comparator<ContainerVolumeData>() {
            @Override
            public int compare(ContainerVolumeData o1, ContainerVolumeData o2) {
                return o1.getContainerPath().compareTo(o2.getContainerPath());
            }
        });
    }


    //docker run --rm -f -v test:test -e test=test maven:test mvn install -f workdir/pom.xml
    //1.默认挂载一个工作卷,用来和上一个容器进行制品共享
    //2.默认环境变量加上_plugin前缀
//    public void create(PluginCreateDto createCommand) {
//        EventSender.send(PluginMapper.INSTANCE.toCreated(createCommand, this.uuid));
//    }
}
